#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行，
# 第2行注释表示.py文件本身使用标准UTF-8编码：
import threading, os

print("#############给线程上锁#############")
balance = 0
lock = threading.Lock()


def change_money(n):
    global balance  # 如果你想要为一个定义在函数外的变量赋值，那么你就得告诉Python这个变量名不是局部的，而是 全局 的。
    balance = balance + n
    balance = balance - n


def run_thread(n):
    print(f'pid:{os.getpid()},change_money:{n},start...')
    for i in range(3000000):
        lock.acquire()  # 获得锁
        try:
            change_money(n)
        finally:
            lock.release()
    print(f'pid:{os.getpid()},change_money:{n},finished...')


t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(8,))
t3 = threading.Thread(target=run_thread, args=(9,))
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
print('balance:', balance)
# 当多个线程同时执行lock.acquire()时，只有一个线程能成功地获取锁，然后继续执行代码，其他线程就继续等待直到获得锁为止。
# 获得锁的线程用完后一定要释放锁，否则那些苦苦等待锁的线程将永远等待下去，成为死线程。所以我们用try...finally来确保锁一定会被释放。
